package in.muton.edushare.mailer;

import java.util.Iterator;
import java.util.List;
import java.util.Properties;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;

import org.apache.cayenne.access.DataContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import com.edushare.common.constants.ConfigPropertyName;
import com.edushare.common.dao.OutgoingEmailsDAO;
import com.edushare.common.global.SystemGlobals;
import com.edushare.common.orm.CayenneORMInterface;
import com.edushare.common.vo.OutgoingEmails;

public class MailThread implements Job {


	private CayenneORMInterface ormInterface;
	private Session session;
	private Transport transport;    
	private Log log = LogFactory.getLog(MailThread.class);

	public static String HOST;
	public static String PORT;
	public static String STARTTLS;
	public static String AUTH;
	public static String USING_SSL;
	public static String SOCKET_FACTORY;
	public static String SOCKET_FACTORY_PORT;
	public static String SOCKET_FACTORY_FALLBACK;
	public static String DEBUG;
	
	public void execute(JobExecutionContext arg0) throws JobExecutionException {
		log.warn("Executed mail job");
	    log.warn("Initializing the system.");
	    DataContext ctxt = DataContext.createDataContext();
	    CayenneORMInterface cayenneIntf = new CayenneORMInterface();
		cayenneIntf.setDataContext(ctxt);
		this.ormInterface = cayenneIntf;
		try{
		List<OutgoingEmails> lst = new OutgoingEmailsDAO(ormInterface).getPendingEmails();
		
		if(lst.size() == 0)
			return;
		} catch(Exception e){
			e.printStackTrace();
		}
		HOST = SystemGlobals.getInstance().getProperties().getProperty("MAIL.HOST");
	    PORT = SystemGlobals.getInstance().getProperties().getProperty("MAIL.PORT");
	    STARTTLS = SystemGlobals.getInstance().getProperties().getProperty("MAIL.STARTTLS");
	    AUTH = SystemGlobals.getInstance().getProperties().getProperty("MAIL.AUTH");
	    USING_SSL = SystemGlobals.getInstance().getProperties().getProperty("MAIL.USING_SSL");
	    SOCKET_FACTORY = SystemGlobals.getInstance().getProperties().getProperty("MAIL.SOCKET_FACTORY");
	    SOCKET_FACTORY_PORT = SystemGlobals.getInstance().getProperties().getProperty("MAIL.SOCKET_FACTORY_PORT");
	    SOCKET_FACTORY_FALLBACK = SystemGlobals.getInstance().getProperties().getProperty("MAIL.SOCKET_FACTORY_FALLBACK");
	    DEBUG = SystemGlobals.getInstance().getProperties().getProperty("MAIL.DEBUG");
	   
	    log.warn("Params: \n" +
	    		"HOST: " + HOST + "\n" + 
	    		"PORT: " + PORT + "\n" + 
	    		"STARTTLS: " + STARTTLS + "\n" + 
	    		"AUTH: " + AUTH + "\n" + 
	    		"USING_SSL: " + USING_SSL + "\n" + 
	    		"SOCKET_FACTORY: " + SOCKET_FACTORY + "\n" + 
	    		"SOCKET_FACTORY_PORT: " + SOCKET_FACTORY_PORT + "\n" + 
	    		"SOCKET_FACTORY_FALLBACK: " + SOCKET_FACTORY_FALLBACK + "\n" +  
	    		"DEBUG: " + DEBUG);

		Properties props = new Properties();
        props.put("mail.smtp.host", HOST);
        props.put("mail.smtp.port", PORT);
        props.put("mail.smtp.auth", AUTH);
        props.put("mail.smtp.starttls.enable", STARTTLS);
        props.put("mail.smtp.debug", DEBUG);
        if(USING_SSL.equalsIgnoreCase("true")){
	        props.put("mail.smtp.socketFactory.port", SOCKET_FACTORY_PORT);
	        props.put("mail.smtp.socketFactory.class", SOCKET_FACTORY);
	        props.put("mail.smtp.socketFactory.fallback", SOCKET_FACTORY_FALLBACK);
        }
	    try {
	    	session = Session.getDefaultInstance(props, null);
	        session.setDebug(true);
		    transport = session.getTransport("smtp");
		    transport.connect(HOST, SystemGlobals.getInstance().getConfigProperty(ConfigPropertyName.MAIL_NOREPLY_USER), 
		    	SystemGlobals.getInstance().getConfigProperty(ConfigPropertyName.MAIL_NOREPLY_PASSWORD));
	    }catch(Exception e){
	        	return;
	    }

		if(transport ==null){
			log.fatal("Could not create transport");
			return;
		}
		
		List<OutgoingEmails> emailList =  new OutgoingEmailsDAO(ormInterface).getPendingEmails();
		log.warn("Starting to send mails.");
		if(emailList.size() == 0){
			log.warn("Mail queue empty.");
		}
		Iterator<OutgoingEmails> emailIt = emailList.iterator();
        
		while(emailIt.hasNext()){
        	log.warn("Sending a mail");
        	
        	OutgoingEmails email = emailIt.next();
        	try{
	        	MimeMessage message = new MimeMessage(session);	        	
	        	message.setSubject(email.getSubject());
	        	message.setContent(email.getContent(),"text/html");
	        	message.setFrom(new InternetAddress(SystemGlobals.getInstance().
	        			getConfigProperty(ConfigPropertyName.MAIL_NOREPLY_USER)));
	        	message.addRecipient(RecipientType.TO, new InternetAddress(email.getReceiverEmailId()));
	        	message.saveChanges();        	
        		transport.sendMessage(message, message.getAllRecipients());
        		log.warn(email.getSubject() + email.getContent()+email.getReceiverEmailId());
        		email.setStatus(OutgoingEmails.EMAIL_SENT);
        		log.warn("Sent mail successfully");
        	}catch(Exception e){
        		log.fatal("Cannot send mail.",e);
        		email.setStatus(OutgoingEmails.EMAIL_SEND_FAIL);
        	}
        }
		try {
			transport.close();
		} catch (MessagingException e) {
			log.error("Error closing Email transport!", e);
			e.printStackTrace();
		}
        ormInterface.getDataContext().commitChanges();
 	}
}
